package me.study.concurrent;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

import org.junit.Test;

/**
 * @author 
 * 原博客文章：http://blog.csdn.net/defonds/article/details/44021605
 * 数组阻塞队列 ArrayBlockingQueue
 *
 */
public class ArrayBlockingQueueTest{
	
	/**
	 * blockingQueue-ArrayBlockingQueue,此队列基于数组实现，因此具有数据的特性，长度一旦指定，无法更改，元素默认以FIFO的方式进行元素的进出
	 * @throws  
	 * BlockingQueue 具有 4 组不同的方法用于插入、移除以及对队列中的元素进行检查。如果请求的操作不能得到立即执行的话，每个方法的表现也不同。这些方法如下：
 		抛异常	特定值	阻塞	超时
		插入	add(o)	offer(o)	put(o)	offer(o, timeout, timeunit)
		移除	remove(o)	poll(o)	take(o)	poll(timeout, timeunit)
		检查	element(o)	peek(o)	 	 

		四组不同的行为方式解释：

    	抛异常：如果试图的操作无法立即执行，抛一个异常。
    	特定值：如果试图的操作无法立即执行，返回一个特定的值(常常是 true / false)。
    	阻塞：如果试图的操作无法立即执行，该方法调用将会发生阻塞，直到能够执行。
    	超时：如果试图的操作无法立即执行，该方法调用将会发生阻塞，直到能够执行，但等待时间不会超过给定值。返回一个特定值以告知该操作是否成功(典型的是 true / false)。
	 */
	@Test
	public void name() throws Exception  {
		class Producer{
			private BlockingQueue<String> blockingQueue;
			public Producer(BlockingQueue<String> queue){
				this.blockingQueue=queue;
			}
			public void produce() throws Exception{
				blockingQueue.put("1");
				System.out.println("插入元素1");
				Thread.sleep(1000);
				blockingQueue.put("2");
				System.out.println("插入元素2");
				Thread.sleep(1000);
				blockingQueue.put("3");
				System.out.println("插入元素3");
				Thread.sleep(1000);
			}
		}
		class Consumer{
			private BlockingQueue<String> blockingQueue;
			public Consumer(BlockingQueue<String> queue){
				this.blockingQueue=queue;
			}
			public void consumer() throws InterruptedException{
				System.out.println("消费者获取元素"+blockingQueue.take());
				System.out.println("消费者获取元素"+blockingQueue.take());
				System.out.println("消费者获取元素"+blockingQueue.take());
			}
		}
		
		
		//测试
		final BlockingQueue<String> blockingQueue=new ArrayBlockingQueue<String>(4);
		new Thread(new Runnable() {//生产者
			public void run() {
				try {
					new Producer(blockingQueue).produce();
				} catch (Exception e) {
					e.printStackTrace();
				};
			}
		}).start();
		new Thread(new Runnable() {//消费者
			public void run() {
				try {
					new Consumer(blockingQueue).consumer();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}).start();
		
		Thread.sleep(5000);
		//测试,如果超出了范围，会报错IllegalStateException
	/*	blockingQueue.add("4");
		blockingQueue.add("4");
		blockingQueue.add("4");
		blockingQueue.add("4");*/
		
		//测试poll的超时方法,结论：超时未取得则返回null
		System.out.println("验证超时开始");
		System.out.println(blockingQueue.poll(3,TimeUnit.SECONDS));
		System.out.println("验证超时完成");
	}
		
	
		
}
